Skip to content

fix(storage): throw instead of crashing on torn WAL tail reads - #1520

Merged
adsharma merged 1 commit into
LadybugDB:mainfrom
adsharma:fix/torn-wal-replay-crash
Nov 6, 2026
Merged

adsharma merged 1 commit into
LadybugDB:mainfrom
adsharma:fix/torn-wal-replay-crash

Conversation

@adsharma

@adsharma adsharma commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

A WAL truncated mid-record (ENOSPC, power loss, SIGKILL mid-commit) crashed recovery with SIGSEGV/SIGBUS in both strict and lenient modes: BufferedFileReader::read copied the full requested size after a page refill without checking the short final page, overrunning the heap buffer inside WALRecord::deserialize <- dryReplay.

This loops small reads across page boundaries and pre-validates large reads against the file size, so torn tails surface as catchable replay errors: strict mode throws, lenient mode drops the torn transaction (verified: strict raises RuntimeError, lenient opens with 0 rows on the 4233-byte repro WAL).

Adds WalTest.TornWALTailInsideLargeStringRecord (verified to die with SIGSEGV without the fix, passes with it). Full WalTest.*, FrozenWALRecoveryTest.*, CheckpointRetryAfterFailureTest.* suites pass (82/82).

Also includes a one-line pre-existing uintmax_t/uint64_t fix in checkpoint_test.cpp needed to build the transaction tests with this toolchain.

BufferedFileReader::read copied the full requested size after a page
refill without checking that the final page held that many bytes, so a
WAL truncated mid-record (ENOSPC, power loss, SIGKILL mid-commit)
overran the heap buffer and crashed recovery with SIGSEGV/SIGBUS in
both strict and lenient modes. Loop small reads across page boundaries
and pre-validate large reads against the file size, so torn tails
surface as catchable replay errors: strict mode throws and lenient mode
drops the torn transaction.

Add WalTest.TornWALTailInsideLargeStringRecord covering a mid-string
truncation of a multi-page WAL in both modes.

Also fix a pre-existing uintmax_t/uint64_t deduction error in
checkpoint_test.cpp that blocked building the transaction tests.
@adsharma
adsharma force-pushed the fix/torn-wal-replay-crash branch from bc86a22 to 1b95688 Compare November 6, 2026 16:26
@adsharma
adsharma merged commit 1e71d93 into LadybugDB:main Nov 6, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant